﻿using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using IdentityModel.Client;
using Microsoft.Extensions.Caching;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;

namespace Mr.Wang.IdentityServerModelPostting
{
    public class IdentityServerModelPostting
    {
        private static MemoryCache tokenMemoryCache = new MemoryCache(Options.Create(new MemoryCacheOptions()));

        /// <summary>
        /// Get异步请求获取目标地址返回内容的字符串
        /// </summary>
        /// <param name="url">目标地址[例如：http://localhost:6001/weatherforecast]</param>
        /// <param name="tokenParam">获取tocken参数，如果是密码模式【PasswordTokenRequest】 获取tocken地址不用填写.[例如:  TokenRequest tokenPar = new TokenRequest() { ClientId = "android", ClientSecret = "12345", GrantType = "client_credentials",Parameters =     {{ "scope", "sendEmail" },  }, }; ]</param>
        /// <param name="tokenUrl">IdentityServer的服务地址.[例如：http://localhost:5000]</param>
        /// <returns>返回null表示失败</returns>
        public async static Task<string> RequestGetAsync(string url, TokenRequest tokenParam, string tokenUrl)
        {
            HttpClient client = null;
            try
            {
                client = new HttpClient();
                //1. 判断是否需要请求tocken
                string key = JsonConvert.SerializeObject(tokenParam);
                string tokenStr = null;
                if (tokenMemoryCache.TryGetValue<string>(key, out string tokenobj))
                {
                    tokenStr = tokenobj;
                }
                else
                {
                    var dios = await client.GetDiscoveryDocumentAsync(tokenUrl);
                    if (dios.IsError)
                    {
                        Console.WriteLine(dios.Error);
                        return default;
                    }
                    tokenParam.Address = dios.TokenEndpoint;
                    client.DefaultRequestHeaders.Accept.Clear();
                    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
                    TokenResponse responseToken = null;
                    if (tokenParam is PasswordTokenRequest request)
                    {
                         responseToken = await client.RequestPasswordTokenAsync(request);
                    }
                    else
                    {
                         responseToken = await client.RequestTokenAsync(tokenParam);
                    }
                 
                    if (responseToken.IsError)
                    {
                        return default;
                    }
                    //获取缓存时间
                    string expireTimeStr = responseToken.TryGet("expires_in");
                    int expireTimeNu = int.Parse(expireTimeStr);
                    tokenStr = tokenMemoryCache.Set<string>(key, responseToken.AccessToken, new TimeSpan(0, 0, expireTimeNu-100));
                }
                client.DefaultRequestHeaders.Accept.Clear();
                client.SetBearerToken(tokenStr);
                var httpResponse = await client.GetAsync(url);

                return await httpResponse.Content.ReadAsStringAsync();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return default;
            }
            finally
            {
                client?.Dispose();
            }

        }

       
        //public async static Task<string> RequestGetAsync(string url, PasswordTokenRequest tokenParam, string tokenUrl)
        //{
        //    HttpClient client = null;
        //    try
        //    {
        //        client = new HttpClient();
        //        //1. 判断是否需要请求tocken
        //        string key = JsonConvert.SerializeObject(tokenParam);
        //        string tokenStr = null;
        //        if (tokenMemoryCache.TryGetValue<string>(key, out string tokenobj))
        //        {
        //            tokenStr = tokenobj;
        //        }
        //        else
        //        {
        //            var dios = await client.GetDiscoveryDocumentAsync(tokenUrl);
        //            if (dios.IsError)
        //            {
        //                Console.WriteLine(dios.Error);
        //                return default;
        //            }
        //            tokenParam.Address = dios.TokenEndpoint;
        //            client.DefaultRequestHeaders.Accept.Clear();
        //            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
        //            var responseToken = await client.RequestPasswordTokenAsync(tokenParam);
        //            if (responseToken.IsError)
        //            {
        //                return default;
        //            }
        //            //获取缓存时间
        //            string expireTimeStr = responseToken.TryGet("expires_in");
        //            int expireTimeNu = int.Parse(expireTimeStr);
        //            tokenStr = tokenMemoryCache.Set<string>(key, responseToken.AccessToken, new TimeSpan(0, 0, expireTimeNu-100));
        //        }
        //        client.DefaultRequestHeaders.Accept.Clear();
        //        client.SetBearerToken(tokenStr);
        //        var httpResponse = await client.GetAsync(url);

        //        return await httpResponse.Content.ReadAsStringAsync();
        //    }
        //    catch (Exception ex)
        //    {
        //        Console.WriteLine(ex.Message);
        //        return default;
        //    }
        //    finally
        //    {
        //        client?.Dispose();
        //    }


        //}
    }
}
